package com.abc.recycling.repository;

import com.abc.recycling.domain.Evaluation;
import com.abc.recycling.repository.provider.EvaluationSqlProvider;
import org.apache.ibatis.annotations.*;
import org.springframework.stereotype.Repository;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Optional;

@Mapper
@Repository
public interface EvaluationRepository {
    
    @SelectProvider(type = EvaluationSqlProvider.class, method = "findByConditions")
    List<Evaluation> findByConditions(Map<String, Object> params);
    
    @Select("SELECT * FROM evaluation WHERE user_id = #{userId}")
    List<Evaluation> findByUserId(@Param("userId") Long userId);
    
    @Select("SELECT * FROM evaluation WHERE target_id = #{collectorId}")
    List<Evaluation> findByCollectorId(@Param("collectorId") Long collectorId);
    
    @Select("SELECT * FROM evaluation WHERE target_id = #{collectorId} ORDER BY create_time DESC LIMIT #{limit}")
    List<Evaluation> findByCollectorIdOrderByCreateTimeDesc(@Param("collectorId") Long collectorId, @Param("limit") int limit);
    
    @Select("SELECT * FROM evaluation WHERE id = #{id}")
    Optional<Evaluation> findById(@Param("id") Long id);
    
    @Select("SELECT EXISTS(SELECT 1 FROM evaluation WHERE order_id = #{orderId})")
    boolean existsByOrderId(@Param("orderId") Long orderId);
    
    @Select("SELECT COUNT(*) FROM evaluation WHERE target_id = #{collectorId}")
    long countByCollectorId(@Param("collectorId") Long collectorId);
    
    @Select("SELECT COUNT(*) FROM evaluation WHERE target_id = #{collectorId} AND create_time >= #{time}")
    long countByCollectorIdAndCreateTimeAfter(@Param("collectorId") Long collectorId, @Param("time") LocalDateTime time);
    
    @Select("SELECT COALESCE(AVG(rating), 0) FROM evaluation WHERE target_id = #{collectorId}")
    Double getAverageRatingByCollectorId(@Param("collectorId") Long collectorId);
    
    @Select("SELECT rating, COUNT(*) as count FROM evaluation WHERE target_id = #{collectorId} GROUP BY rating ORDER BY rating")
    @Results({
        @Result(column = "rating", property = "rating"),
        @Result(column = "count", property = "count")
    })
    List<Map<String, Object>> getRatingDistributionByCollectorId(@Param("collectorId") Long collectorId);
    
    @SelectProvider(type = EvaluationSqlProvider.class, method = "searchEvaluations")
    List<Evaluation> searchEvaluations(
            @Param("userId") Long userId,
            @Param("collectorId") Long collectorId,
            @Param("status") Integer status,
            @Param("minRating") Double minRating,
            @Param("maxRating") Double maxRating);
            
    @Insert("INSERT INTO evaluation (user_id, target_id, order_id, rating, content, status, create_time, update_time) " +
           "VALUES (#{userId}, #{collectorId}, #{orderId}, #{rating}, #{comment}, #{status}, #{createTime}, #{updateTime})")
    @Options(useGeneratedKeys = true, keyProperty = "id")
    Evaluation save(Evaluation evaluation);
    
    @Update("UPDATE evaluation SET " +
           "reply = #{reply}, " +
           "reply_time = #{replyTime}, " +
           "update_time = #{updateTime} " +
           "WHERE id = #{id}")
    int update(Evaluation evaluation);
    
    @Delete("DELETE FROM evaluation WHERE id = #{id}")
    void deleteById(@Param("id") Long id);
    
    @Select("SELECT COUNT(*) FROM evaluation WHERE target_id = #{collectorId} AND rating = #{rating}")
    long countByCollectorIdAndRating(@Param("collectorId") Long collectorId, @Param("rating") int rating);
} 